package me.aartikov.alligator.navigators;


import me.aartikov.alligator.animations.AnimationData;
import me.aartikov.alligator.animations.DialogAnimation;
import me.aartikov.alligator.exceptions.NavigationException;
import me.aartikov.alligator.listeners.DialogShowingListener;
import me.aartikov.alligator.listeners.ScreenResultListener;
import me.aartikov.alligator.Screen;
import me.aartikov.alligator.ScreenResult;
import me.aartikov.alligator.animations.providers.DialogAnimationProvider;
import me.aartikov.alligator.destinations.DialogFragmentDestination;
import me.aartikov.alligator.helpers.DialogFraction;
import me.aartikov.alligator.helpers.DialogFractionHelper;
import me.aartikov.alligator.helpers.ScreenResultHelper;
import me.aartikov.alligator.navigationfactories.NavigationFactory;
import ohos.aafwk.ability.fraction.FractionManager;

public class DefaultDialogFragmentNavigator implements DialogFragmentNavigator {

    private DialogFractionHelper mDialogFragmentHelper;


    private NavigationFactory mNavigationFactory;


    private ScreenResultHelper mScreenResultHelper;


    private DialogShowingListener mDialogShowingListener;


    private ScreenResultListener mScreenResultListener;


    private DialogAnimationProvider mAnimationProvider;

    public DefaultDialogFragmentNavigator(FractionManager fragmentManager,
                                          NavigationFactory navigationFactory,
                                          DialogShowingListener dialogShowingListener,
                                          ScreenResultListener screenResultListener,
                                          DialogAnimationProvider animationProvider) {
        mDialogFragmentHelper = new DialogFractionHelper(fragmentManager);
        mNavigationFactory = navigationFactory;
        mScreenResultHelper = new ScreenResultHelper(mNavigationFactory);
        mDialogShowingListener = dialogShowingListener;
        mScreenResultListener = screenResultListener;
        mAnimationProvider = animationProvider;
    }

    @Override
    public void goForward(Screen screen,
                          DialogFragmentDestination destination,
                          AnimationData animationData) throws NavigationException {

        DialogFraction dialogFragment = destination.createDialogFragment(screen);
        DialogAnimation animation = mAnimationProvider.getAnimation(screen.getClass(), animationData);
        mDialogFragmentHelper.showDialog(dialogFragment, animation);
        mDialogShowingListener.onDialogShown(screen.getClass());
    }

    @Override
    public void replace(Screen screen,
                        DialogFragmentDestination destination,
                        AnimationData animationData) throws NavigationException {
        if (mDialogFragmentHelper.isDialogVisible()) {
            mDialogFragmentHelper.hideDialog();
        }

        DialogFraction dialogFragment = destination.createDialogFragment(screen);
        DialogAnimation animation = mAnimationProvider.getAnimation(screen.getClass(), animationData);
        mDialogFragmentHelper.showDialog(dialogFragment, animation);
        mDialogShowingListener.onDialogShown(screen.getClass());
    }

    @Override
    public void reset(Screen screen,
                      DialogFragmentDestination destination,
                      AnimationData animationData) throws NavigationException {

        while (mDialogFragmentHelper.isDialogVisible()) {
            mDialogFragmentHelper.hideDialog();
        }

        DialogFraction dialogFragment = destination.createDialogFragment(screen);
        DialogAnimation animation = mAnimationProvider.getAnimation(screen.getClass(), animationData);
        mDialogFragmentHelper.showDialog(dialogFragment, animation);
        mDialogShowingListener.onDialogShown(screen.getClass());
    }

    @Override
    public boolean canGoBack() {
        return mDialogFragmentHelper.isDialogVisible();
    }

    @Override
    public void goBack(ScreenResult screenResult) throws NavigationException {
        DialogFraction dialogFragment = mDialogFragmentHelper.getDialogFragment();
        mDialogFragmentHelper.hideDialog();
        if (dialogFragment != null) {
            mScreenResultHelper.callScreenResultListener(dialogFragment, screenResult, mScreenResultListener);
        }
    }




    @Override
    public DialogFraction getCurrentDialogFragment() {
        return mDialogFragmentHelper.getDialogFragment();
    }
}
